#ifndef XGE_XMAINLOOP_H_
#define XGE_XMAINLOOP_H_
#include "xge_common_config.h"
#include "xtimer.h"
#include "xsmart_ptr.h"

namespace xge{
  // Forward declaration
namespace event {
  class EventManager;
}
namespace graphics {
  class SceneManager;
}

  class XGameEngine;
  using xge_internal::Timer;
  using xge_internal::IntrinsicPointer;

  class MainLoopOnIdleListener : public IntrinsicPointer< MainLoopOnIdleListener > {
  public:
    virtual void OnIdle( ) = 0;
    virtual ~MainLoopOnIdleListener() {}
  };

  // Main loop is the class which manage the loop stuff here , it manipulate the
  // loop by using LoopSync class callback ! It allows you to set the loop callback
  // and frame rate here !

  class MainLoop {
  public:
    // When calling this function , the whole system will start to loop until 
    // specific event has been triggered and the loop will break !
    void Loop();
    // When calling this function , the main application will exit 
    // This is always the pretty nice way to exit the main loop .
    // This quitting is ASYNCHRONIZED way ,that means , after calling
    // this function , which do not mean that the application will
    // exit at once .The best way to do so , is calling this function
    // inside of the callback in the EventLoop
    void QuitApplication() ;
  public:
    // The following function allows you to set up the resolution of this loop 
    // It internally allows you to set up the timer for the loop ticking , etc ,
    // how many loops per seconds , it will affects the EventManager and SceneManager 
    void set_resolution( int resolution ) {
      resolution_ = resolution;
      time_ = (1000/resolution);
    }
    int resolution() const {
      return resolution_;
    }

    void set_on_idle_listener( MainLoopOnIdleListener* listener ) {
      if( on_idle_listener_ )
        on_idle_listener_->Drop();
      if( listener )
        listener->Grab();
      on_idle_listener_ = listener ;
    }

  private:

    MainLoop( event::EventManager* event_mgr , graphics::SceneManager* scene_mgr ) :
         event_mgr_(event_mgr),scene_mgr_(scene_mgr),on_idle_listener_(NULL),quit_(false){
           // set the resolution to 1000 , which means the infinite mode of frame control
           set_resolution(1000);
         }

    ~MainLoop() {
      if( on_idle_listener_ )
        on_idle_listener_->Drop();
    }

  private:
    int resolution_ ;
    Timer::tick_t last_loop_time_;
    Timer::tick_t time_;
    Timer timer_;
    event::EventManager* event_mgr_;
    graphics::SceneManager* scene_mgr_;
    MainLoopOnIdleListener* on_idle_listener_ ;
    bool quit_ ;

    friend class XGameEngine;
  };






}// namespace xge





#endif// XGE_XMAINLOOP_H_